import { defineStore } from 'pinia'
import { ref, computed } from 'vue'

export const useCacheStore = defineStore('cache', () => {
  // 缓存数据
  const cache = ref(new Map())
  const cacheTimestamps = ref(new Map())
  
  // 缓存配置
  const defaultTTL = 5 * 60 * 1000 // 5分钟
  const maxCacheSize = 100 // 最大缓存条目数
  
  // 缓存统计
  const cacheStats = ref({
    hits: 0,
    misses: 0,
    size: 0
  })
  
  const hitRate = computed(() => {
    const total = cacheStats.value.hits + cacheStats.value.misses
    return total > 0 ? (cacheStats.value.hits / total * 100).toFixed(2) : 0
  })
  
  // 设置缓存
  const set = (key, value, ttl = defaultTTL) => {
    const now = Date.now()
    
    // 检查缓存大小限制
    if (cache.value.size >= maxCacheSize) {
      // 删除最旧的缓存项
      const oldestKey = cacheTimestamps.value.keys().next().value
      if (oldestKey) {
        cache.value.delete(oldestKey)
        cacheTimestamps.value.delete(oldestKey)
      }
    }
    
    cache.value.set(key, value)
    cacheTimestamps.value.set(key, now + ttl)
    cacheStats.value.size = cache.value.size
  }
  
  // 获取缓存
  const get = (key) => {
    const now = Date.now()
    const expiry = cacheTimestamps.value.get(key)
    
    // 检查是否过期
    if (expiry && now > expiry) {
      cache.value.delete(key)
      cacheTimestamps.value.delete(key)
      cacheStats.value.misses++
      cacheStats.value.size = cache.value.size
      return null
    }
    
    if (cache.value.has(key)) {
      cacheStats.value.hits++
      return cache.value.get(key)
    }
    
    cacheStats.value.misses++
    return null
  }
  
  // 删除缓存
  const remove = (key) => {
    const existed = cache.value.has(key)
    cache.value.delete(key)
    cacheTimestamps.value.delete(key)
    cacheStats.value.size = cache.value.size
    return existed
  }
  
  // 检查缓存是否存在
  const has = (key) => {
    const now = Date.now()
    const expiry = cacheTimestamps.value.get(key)
    
    if (expiry && now > expiry) {
      cache.value.delete(key)
      cacheTimestamps.value.delete(key)
      cacheStats.value.size = cache.value.size
      return false
    }
    
    return cache.value.has(key)
  }
  
  // 清除所有缓存
  const clear = () => {
    cache.value.clear()
    cacheTimestamps.value.clear()
    cacheStats.value.size = 0
  }
  
  // 清除过期缓存
  const clearExpired = () => {
    const now = Date.now()
    const expiredKeys = []
    
    for (const [key, expiry] of cacheTimestamps.value.entries()) {
      if (now > expiry) {
        expiredKeys.push(key)
      }
    }
    
    expiredKeys.forEach(key => {
      cache.value.delete(key)
      cacheTimestamps.value.delete(key)
    })
    
    cacheStats.value.size = cache.value.size
    return expiredKeys.length
  }
  
  // 获取缓存键列表
  const keys = () => {
    return Array.from(cache.value.keys())
  }
  
  // 获取缓存大小
  const size = computed(() => cache.value.size)
  
  // 缓存API响应
  const cacheApiResponse = async (key, apiCall, ttl = defaultTTL) => {
    // 先检查缓存
    const cached = get(key)
    if (cached) {
      return cached
    }
    
    // 调用API
    try {
      const response = await apiCall()
      set(key, response, ttl)
      return response
    } catch (error) {
      throw error
    }
  }
  
  // 预加载数据
  const preload = async (key, apiCall, ttl = defaultTTL) => {
    try {
      const response = await apiCall()
      set(key, response, ttl)
      return response
    } catch (error) {
      console.warn(`预加载失败: ${key}`, error)
      return null
    }
  }
  
  // 批量清除缓存
  const clearByPattern = (pattern) => {
    const regex = new RegExp(pattern)
    const keysToDelete = []
    
    for (const key of cache.value.keys()) {
      if (regex.test(key)) {
        keysToDelete.push(key)
      }
    }
    
    keysToDelete.forEach(key => {
      cache.value.delete(key)
      cacheTimestamps.value.delete(key)
    })
    
    cacheStats.value.size = cache.value.size
    return keysToDelete.length
  }
  
  return {
    // 状态
    cacheStats,
    hitRate,
    size,
    
    // 方法
    set,
    get,
    remove,
    has,
    clear,
    clearExpired,
    keys,
    cacheApiResponse,
    preload,
    clearByPattern
  }
})
